using System.Collections;
using System.Collections.Generic;
using cframework;


public static class GitTool
{
    public static string GitPath
    {
        get
        {
            if(System.IO.File.Exists("/usr/local/bin/git"))
            {
                return "/usr/local/bin/git";
            }
            else
            {
                return "git";
            }
        }

        set{}
    }


    public static bool HasChanges(string projectPath)
    {
        string dir = System.IO.Path.GetDirectoryName(projectPath);
        var ret = CommandLineTool.RunCommand2(GitPath, "status -s .", projectPath);
        if (ret.ExitCode != 0)
        {
            throw new System.Exception("git cmd failed: " + GitPath);
        }


        using (System.IO.StringReader reader = new System.IO.StringReader(ret.StdOut))
        {
            do
            {
                string line = reader.ReadLine();
                if(line == null)
                {
                    return false;
                }

                line = line.Trim();
                if(!string.IsNullOrEmpty(line))
                {
                    return true;
                }
            }while(true);
        }

        return true;
    }

    public static string GetBranchName(string path)
    {
        string dir = System.IO.Path.GetDirectoryName(path);
        var ret = CommandLineTool.RunCommand2(GitPath, "branch --show-current ", path);
        if (ret.ExitCode != 0)
        {
            return null;
        }

        var output = ret.StdOut.Replace("\n", "").Replace("\r", "");
        return output;
    }

    public static bool IsGitRespository(string path)
    {
        var ret = CommandLineTool.RunCommand2(GitPath, "status", path);
        return ret.ExitCode == 0;
    }

    public static string GetConfigByKey(string path, string key)
    {
        if(!System.IO.Directory.Exists(path))
        {
            return null;
        }

        string dir = System.IO.Path.GetDirectoryName(path);
        var ret = CommandLineTool.RunCommand2(GitPath, "config " + key, path);
        if (ret.ExitCode != 0)
        {
            return null;
        }

        var output = ret.StdOut.Replace("\n", "").Replace("\r", "");
        return output;
    }


    
    public static string GetProjectLastChangedVersion(string path)
    {
        // string dir = System.IO.Path.GetDirectoryName(path);
        var ret = CommandLineTool.RunCommand2(GitPath, "log -1 --format=%H ", path);
        if (ret.ExitCode != 0)
        {
            return null;
        }

        var output = ret.StdOut.Replace("\n", "").Replace("\r", "");
        return output;
    }

    public static bool Clone(string gitPath, string localPath)
    {
        var ret = CommandLineTool.RunCommand2(GitPath, "clone " + gitPath + " " + localPath, UnityEngine.Application.dataPath);
        if (ret.ExitCode != 0)
        {
            UnityEngine.Debug.LogError(ret.StdOut);
            UnityEngine.Debug.LogError(ret.StdErr);
            return false;
        }

        return true;
    }

    public static bool Add(string projectPath, string addPath)
    {
        var ret = CommandLineTool.RunCommand2(GitPath, "add " + addPath, projectPath);
        if (ret.ExitCode != 0)
        {
            UnityEngine.Debug.LogError(ret.StdOut);
            UnityEngine.Debug.LogError(ret.StdErr);
            return false;
        }

        return true;
    }

    public static bool Commit(string projectPath, string msg)
    {
        var ret = CommandLineTool.RunCommand2(GitPath, $"commit -m \"{msg}\"", projectPath);
        if (ret.ExitCode != 0)
        {
            UnityEngine.Debug.LogError(ret.StdOut);
            UnityEngine.Debug.LogError(ret.StdErr);
            return false;
        }

        return true;
    }

    public static bool Push(string projectPath)
    {
        string branchName = GetBranchName(projectPath);

        var ret = CommandLineTool.RunCommand2(GitPath, $"push -u origin {branchName}", projectPath);
        if (ret.ExitCode != 0)
        {
            UnityEngine.Debug.LogError(ret.StdOut);
            UnityEngine.Debug.LogError(ret.StdErr);
            return false;
        }

        return true;
    }

    public static bool Restore(string projectPath, string restorePath, bool staged = false)
    {
        var ret = CommandLineTool.RunCommand2(GitPath, "restore " + (staged ? "--staged " : "") + restorePath, projectPath);
        if (ret.ExitCode != 0)
        {
            UnityEngine.Debug.LogError(ret.StdOut);
            UnityEngine.Debug.LogError(ret.StdErr);
            return false;
        }

        return true;
    }

    public static bool Clean(string path)
    {
        var ret = CommandLineTool.RunCommand2(GitPath, "clean -fd", path);
        if (ret.ExitCode != 0)
        {
            UnityEngine.Debug.LogError(ret.StdOut);
            UnityEngine.Debug.LogError(ret.StdErr);
            return false;
        }

        return true;
    }

    public static bool CheckoutBranch(string path, string branchName)
    {
        var ret = CommandLineTool.RunCommand2(GitPath, "checkout " + branchName, path);
        if (ret.ExitCode != 0)
        {
            UnityEngine.Debug.LogError(ret.StdOut);
            UnityEngine.Debug.LogError(ret.StdErr);
            return false;
        }

        return true;
    }

    public static bool CreateOrphanBranch(string path, string branchName)
    {
        {
            var ret = CommandLineTool.RunCommand2(GitPath, "checkout --orphan " + branchName, path);
            if (ret.ExitCode != 0)
            {
                UnityEngine.Debug.LogError(ret.StdOut);
                UnityEngine.Debug.LogError(ret.StdErr);
                return false;
            }
        }




        {
            var ret = CommandLineTool.RunCommand2(GitPath, "rm -rf .", path);
            if (ret.ExitCode != 0)
            {
                UnityEngine.Debug.LogError(ret.StdOut);
                UnityEngine.Debug.LogError(ret.StdErr);
                return false;
            }
        }
        
        return true;
    }

    public static int GetVersionNumber(string path)
    {
        var ret = CommandLineTool.RunCommand2(GitPath, "log --format=%H", path);
        if (ret.ExitCode != 0)
        {
            return -1;
        }

        string[] versions = ret.StdOut.Split('\n');
        return versions.Length;
    }
}